
//#pragma execution_character_set("utf-8")
#include "Worker.h"
#include "Dream3DRender.h"
#include "well.h"
#include <QDebug>
#include <QMessageBox>

// 用来判断线程退出的标志
int myFlag = 1;

Worker* gWrok = nullptr;

void gMessageFunction(std::string msg, int state, float per)
{
  if (gWrok)
  {
    gWrok->MessageFunction(QString::fromLocal8Bit(msg.c_str()), state, per);
  }
}
Worker::Worker(MessageStateCall function, QObject* parent) : QThread(parent), mFunction(function)
{
  gWrok = this;
}

Worker::~Worker()
{
  DeleteHasAtts();
}

std::vector<std::vector<Name_Loc>> Worker::GetDynamicTable()
{
  return mGrid.dym_props;
}

std::vector<Name_Loc> Worker::GetStaticTable()
{
  return mGrid.stat_props;
}

double Worker::GetValue(int iselfield, vsg::ivec3 ijk)
{
  return mGrid.GetValue(iselfield, ijk);
}

void Worker::Filter()
{
  //mGrid.FilterAttDebug();
}

RenderData* Worker::NewRenderData()
{
  return new RenderData();
}

void Worker::DeleteRenderData(RenderData* pData)
{
  if (pData)
  {
    delete pData;
  }
}

void Worker::DeleteHasAtts() 
{
  MAP_PropArray::iterator itAtt;
  MAP_PropArray::iterator itAttBegin = mHasAtts.begin();
  MAP_PropArray::iterator itAttEnd   = mHasAtts.end();
  for (itAtt = itAttBegin; itAtt != itAttEnd; ++itAtt)
  {
    if (itAtt->second)
    {
      delete itAtt->second;
    }
  }
  mHasAtts.clear();
}

void Worker::run()
{
  if (mType == 1)
  {
    std::string casename = mFilePath.toStdString();
    mGrid.SetFilePath(casename);
    clock_t start_time = std::clock();
    mGrid.SetCallBack(gMessageFunction);
    mGrid.InitData();
    clock_t end_time = std::clock();

    // this->MessageFunction(,1,100);
    emit sendMsgToMain(QString::fromLocal8Bit("初始化数据完成,请选择属性再添加网格"), 10, 100);
  }
  if (mType == 2)
  {
    if (mSelFields.size() < 1)
    {
      QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("选择的属性错误"));
      return;
    }
    ofstream log;
    log.open("GetValues.txt");
    clock_t start_time = std::clock();
    emit sendMsgToMain(QString::fromLocal8Bit("获取属性."), 1, 5);

    // for (int k = 0; k < mAtts.size(); ++k)
    //{
    //   delete mAtts[k];
    // }
    mAtts.clear();

    std::vector<ReadAttWorker*> readThreads;
    MAP_PropArray::iterator itFindAtts;
    ofstream logerror;
    logerror.open("error.txt");
    for (int k = 0; k < mSelFields.size(); ++k)
    {
      itFindAtts = mHasAtts.find(mSelFields[k].field.toStdString());
      if (itFindAtts != mHasAtts.end())
      {
        mAtts.push_back(itFindAtts->second);
        continue;
      }
      PropArray* pArray = new PropArray();
      mAtts.push_back(pArray);
      std::string strField       = mSelFields[k].field.toStdString();
      ReadAttWorker* pReadThread = new ReadAttWorker(&mGrid, mSelFields[k].id, strField, pArray);
      readThreads.push_back(pReadThread);
      pReadThread->start();
    }
    VEC_PropArray attsOk;
    for (int k = 0; k < readThreads.size(); ++k)
    {
      readThreads[k]->wait();
      if (mAtts[k]->length <= 0)
      {
        logerror << mSelFields[k].field.toStdString() << "获取属性失败" << std::endl;
        emit sendMsgToMain(mSelFields[k].field + QString::fromLocal8Bit("获取属性失败"), 1, (100.0 * k) / readThreads.size());
      }
      // else
      //{
      //   attsOk.push_back(mAtts[k]);
      // }
      delete readThreads[k];
      emit sendMsgToMain(mSelFields[k].field + QString::fromLocal8Bit("获取属性完成"), 1, (100.0 * k) / readThreads.size());
    }
    readThreads.clear();
    logerror.close();
    emit sendMsgToMain(QString::fromLocal8Bit("获取属性完成."), 1, 100);

    clock_t end_time = std::clock();
    log << "扫描数据时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;

    RenderData* renderData = NewRenderData();
    mGrid.BuildGrid();

    for (int k = 0; k < mAtts.size(); ++k)
    {
      mHasAtts[mAtts[k]->name] = mAtts[k];
    }
    emit sendMsgToMain(QString::fromLocal8Bit("网格创建中..."), 1, 50);
    mGrid.GenGridRenderData(renderData, mAtts);

    vsg::vec3 center = (renderData->box.max + renderData->box.min) * 0.5f;
    if (mbInitSceneCenter)
    {
      center = mCenter;
    }
    else
    {
      mCenter           = vsg::dvec3(center.x, center.y, center.z);
      mbInitSceneCenter = true;
    }
    renderData->box = vsg::box(renderData->box.min - center, renderData->box.max - center);

#pragma omp parallel for
    for (long long k = 0; k < renderData->vertices->size(); ++k)
    {
      vsg::vec3& vec = renderData->vertices->at(k);
      vec[0] -= center.x;
      vec[1] -= center.y;
      vec[2] -= center.z;
    }
    emit SendDataToMain(renderData, 2);
    emit sendMsgToMain(QString::fromLocal8Bit("网格创建完成."), 1, 100);
  }
  if (mType == 3)
  {
    if (mWellField.size() < 1)
    {
      emit sendMsgToMain(QString::fromLocal8Bit("添加井数据,未选择属性"), 1, 100);
      return;
    }
    QMap<int, QMap<QString, QVector<WellPoint>>> wells;
    QString error2;
    WellPoint::readWell(mWellPath, wells, error2);

    vsg::vec3 p1(0, 0, 0);
    vsg::vec3 p2(0, 0, 1);
    float radius = 10;
    int segnum   = 18;
    std::vector<vsg::vec3> vertices;
    std::vector<int> indices;
    std::vector<vec3> ids;
    int offset = 0;
    QMap<int, QMap<QString, QVector<WellPoint>>>::iterator it;

    vsg::vec3 vecmin(10000000, 10000000, 10000000);
    vsg::vec3 vecmax(-10000000, -10000000, -10000000);
    std::vector<vec4> values;
    double valueSpanMin = -1 * InvalidValue;
    double valueSpanMax = InvalidValue;

    QString strField = mWellField[0];

    for (it = wells.begin(); it != wells.end(); ++it)
    {
      QMap<QString, QVector<WellPoint>>& well = it.value();
      QMap<QString, QVector<WellPoint>>::iterator itWell;
      QMap<QString, QVector<WellPoint>>::iterator itWellBegin = well.begin();
      QMap<QString, QVector<WellPoint>>::iterator itWellEnd   = well.end();
      int id                                                  = 1;
      for (itWell = itWellBegin; itWell != itWellEnd; ++itWell, ++id)
      {
        QVector<WellPoint>& wellLayers = itWell.value();
        for (int kLayer = 0; kLayer < wellLayers.size() - 1; ++kLayer)
        {
          WellPoint& layer = wellLayers[kLayer];
          p1.x             = layer.x;
          p1.y             = layer.y;
          p1.z             = -layer.z;

          p2.x = wellLayers[kLayer + 1].x;
          p2.y = wellLayers[kLayer + 1].y;
          p2.z = -wellLayers[kLayer + 1].z;

          vecmin.x = std::min(vecmin.x, p1.x - radius);
          vecmin.y = std::min(vecmin.y, p1.y - radius);
          vecmin.z = std::min(vecmin.z, p1.z);

          vecmax.x = std::max(vecmax.x, p1.x + radius);
          vecmax.y = std::max(vecmax.y, p1.y + radius);
          vecmax.z = std::max(vecmax.z, p2.z);

          std::vector<vsg::vec3> verticesTem;
          std::vector<int> indicesTem;
          generateCylinderMesh(p1, p2, radius, segnum, verticesTem, indicesTem, 0);
          for (int k = 0; k < verticesTem.size(); ++k)
          {
            ids.push_back(vsg::vec3(id, kLayer, 0));
          }
          QMap<QString, double>::iterator itFindValue = layer.properties.find(strField);
          double dValue                               = kLayer;
          if (itFindValue != layer.properties.end())
          {
            dValue = itFindValue.value();
          }
          for (int k = 0; k < verticesTem.size(); ++k)
          {
            values.push_back(vsg::vec4(dValue, 0, 0, 0));
          }
          valueSpanMin = std::min(dValue, valueSpanMin);
          valueSpanMax = std::max(dValue, valueSpanMax);

          // for (int k = 0; k < verticesTem.size(); ++k)
          //{
          //   normals.push_back(vsg::vec3(id, kLayer, 0));
          // }
          vertices.insert(vertices.end(), verticesTem.begin(), verticesTem.end());
          for (int ii = 0; ii < indicesTem.size(); ++ii)
          {
            indices.push_back(indicesTem[ii] + offset);
          }
          offset = vertices.size();
        }
        // break;
      }
      break;
    }
    RenderData* renderdata = NewRenderData();
    renderdata->SetPointSize(vertices.size());
    renderdata->SetIndicesSize(indices.size());

    renderdata->box   = vsg::box(vecmin, vecmax);
    vsg::vec3 center  = (renderdata->box.max + renderdata->box.min) * 0.5f;
    if (mbInitSceneCenter)
    {
      center = mCenter;
    }
    else
    {
      mCenter           = vsg::dvec3(center.x, center.y, center.z);
      mbInitSceneCenter = true;
    }
    renderdata->box = vsg::box(renderdata->box.min - center, renderdata->box.max - center);

    double dValueSpan = valueSpanMax - valueSpanMin;
#pragma omp parallel for
    for (int k = 0; k < vertices.size(); ++k)
    {
      renderdata->vertices->at(k) = vertices[k] - center;
      renderdata->normals->at(k)  = vertices[k];
      renderdata->ijks->at(k)     = ids[k];
      if (dValueSpan > 0)
      {
        renderdata->texcoords->at(k) = vsg::vec4(values[k].x / dValueSpan, 0, 0, 0);
      }
      else
      {
        renderdata->texcoords->at(k) = vsg::vec4((1.0 * k) / vertices.size(), 0, 0, 0);
      }
    }
    int* pData = (int*)renderdata->indices->dataPointer();
    memcpy(pData, &indices[0], sizeof(int) * indices.size());

    emit SendDataToMain(renderdata, 3);
    emit sendMsgToMain(QString::fromLocal8Bit("井数据创建完成."), 1, 100);
  }
}


void Worker::MessageFunction(QString msg, int state, float per)
{
  emit sendMsgToMain(msg, state, per);
}

void Worker::recMegFromMain(QString str)
{
  // qDebug() << str;
}

void ReadAttWorker::run()
{
  if (mpOutAtts == nullptr || mpOutAtts == nullptr || mIndex < 0 || mField.length() < 1)
  {
    return;
  }
  mGrid->GetValue(mIndex, mField, *mpOutAtts);
}
